int stepCount = 0; //count of steps, including multiple simulated steps (used mainly for recording)

Vector3d bufferA = new Vector3d(0,0,0); //reserved for Particle class
Vector3d bufferB = new Vector3d(0,0,0); //reserved for Particle class
Vector3d bufferC = new Vector3d(0,0,0); //reserved for Vector3d class
Vector3d bufferD = new Vector3d(0,0,0); //reserved for Vector3d class
Vector3d bufferE = new Vector3d(0,0,0); //reserved for SolidWall2d class
Vector3d bufferF = new Vector3d(0,0,0); //reserved for SolidWall2d class
Vector3d bufferG = new Vector3d(0,0,0); //reserved for SolidWall2d class
Vector3d bufferH = new Vector3d(0,0,0); //reserved for SolidWall2d class

int bgcolor = 0;

Vector3d goalLocation;

final boolean drawing3d = false;
final boolean sphere3d = false;
boolean alreadyWonLevel;
final float defaultFriction = 0.1;
final float defaultForceConstant = 1.0;
final float defaultRadius = 5.0;
final float defaultDelta = 1.0;
final Vector3d defaultColor = new Vector3d(255,255,255);

String inputLevelString;
String levelString = "";
//With tstep .015, stepsPerFrame 3, springConstant ~8100 is the "edge"; 7000 is stable, in between we get "quantum" uncertainty (half-blowups)
//tstep .015, stepsPerFrame 10
float springConstant = 1900.0;
float MAX_SPRING_CONSTANT = 15000.0;
//final Vector3d zero = new Vector3d(0,0,-480);
//final Vector3d maxV = new Vector3d(640,480,0);
final int stepsPerFrame = 5;
float curlThresh = 20.0;
float curlSens = 0.05;
int currentLevel = 1;
String levelLocation = "level1.rgb";
float tstep = 0.015;
int constraintIters = 2;
float myMass = 1.0;
float myColorMass = 1.4*myMass;
float myRadius = 3.0;
float myColorRadius = myRadius*1.2;
float myLegLength = 30.0;
float legExtendFactor = 1.8;
float gravityStrength = 1700.0;
float mouseSpinStrength = 2000;
float maxAbsSpin = 12000;
float camFollowSpeed = .05;
float myXMultiplier = 1.0; //camera follow speed stuff
float myYMultiplier = 1.0;
boolean debugFlag = false;

final int REDINDEX = 1;
final int GREENINDEX = 2;
final int BLUEINDEX = 3;

boolean redGrabbing = false;
boolean greenGrabbing = false;
boolean blueGrabbing = false;
boolean alphaGrabbing = false;
float mouseForce = 0.0;
boolean invertedRGB = false; //flag set if RGB pops inside out - normally ordered clockwise RGB; if counterclockwise, this should be flagged
float angularVelocity = 0.0;
float smoothedAngularVelocity = 0.0;
float smoothedMouseForce = 0.0;
float origKeySpinFactor = .5;
float keySpinFactor = origKeySpinFactor;
float keySpinAccel = .002;

boolean spinBurst = false;//true; //controls whether spin forces cause particle ejection

final Vector3d ZEROVEC = new Vector3d(0,0,0);
final Vector3d WHITEVEC = new Vector3d(255,255,255);
final Vector3d REDVEC = new Vector3d(255,0,0);
final Vector3d GREENVEC = new Vector3d(0,255,0);
final Vector3d BLUEVEC = new Vector3d(0,0,255);


boolean keyState[] = new boolean[256];
boolean keyLeft,keyRight;
boolean rePose = true;

Particle myParticle[] = new Particle[10];
Player myPlayer;
Pose myPose;
//Particle worldParticles[];
//SolidWall2d myWall[];
ArrayList myWall; //List of all walls
ArrayList otherParticle; //List of non-player particles that _do_ collide with scenery
ArrayList otherParticleNoCollide; //currently not used...implement this, though, it will be useful

Strut[] redStruts;
Strut[] greenStruts;
Strut[] blueStruts;    //Lists of red, blue, and green struts (only used for collision detection, not constraint application)
Strut[] alphaStruts;
ArrayList myStrut; //List of all non-dynamical struts - better to copy this into a flat array and access from there!
ArrayList redDStruts;
ArrayList greenDStruts;
ArrayList blueDStruts; //dynamical struts (i.e. the ones that are used to hold the player to a rope and thus appear/disappear)
ArrayList alphaDStruts;
ArrayList myStaticCStruts;//All non-moving colliding struts (pinned particle on both ends)
ArrayList myDynamicCStruts;//Moving colliding struts

ArrayList allParticles; //Low level complete lists of particles/struts to look up by ID number
ArrayList allStruts;

//If we're grabbing a strut, we don't draw or apply the original strut, we draw the resulting ones - the original is stored away
Strut rnodrawStrut;
Strut gnodrawStrut;
Strut bnodrawStrut;

int numWalls;
Vector3d collidePoint;
Vector3d gravityForce;
float cameraX, cameraY, cameraZ;
SpatialPartition mySpatialPartition;

//PImage noiseTile;
PImage testImage;
Sprite testSprite;

int frameNumber;

Particle[] fxParticles;
//Particle bufferFXParticle;
int numFXParticles = 2000;
int activeFXParticles = 0;
